﻿using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http.Filters;
using DapperWrapper;

using ZLWeb.WebApiConfigration;
using ZLWeb.WebApiEntity;
using ZLWeb.WebApiInfrastructure.CustomerException;
using ZLWeb.WebApiRepository;
using ZLWeb.WebApiRepository.InterFace;

namespace ZLWeb.WebApiInfrastructure.Filter
{
    /// <summary>
    ///     异常全局处理类
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
    public class ExceptionAttribute : ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext.Exception.GetType().Name.Contains("Pipe"))
            {
                HandlePipeException(actionExecutedContext);
            }
            else
            {
                HandleException(actionExecutedContext);
            }

          
            base.OnException(actionExecutedContext);
        }

        /// <summary>
        ///     处理管道内错误
        /// </summary>
        /// <param name="PipeException"></param>
        /// <returns></returns>
        //todo 发生错误后的SQL补偿
        public virtual void HandlePipeException(HttpActionExecutedContext actionExecutedContext)
        {

            actionExecutedContext.Response =
                actionExecutedContext.Request.CreateResponse(HttpStatusCode.ServiceUnavailable,
                    new ResponseResultInfo
                    {
                        description = actionExecutedContext.Exception.Message,
                        number = "-1",
                        type = "pipeunknownException",
                        RandomCode =
                            actionExecutedContext.Request.Headers.FirstOrDefault(x => x.Key == "RandomCode")
                                .Value.FirstOrDefault(),
                        httpcode = 503
                    });
        }

        //todo 要判断是否是VB调用的，errmoel要单独包装
        public virtual void HandleException(HttpActionExecutedContext actionExecutedContext)
        {
            ////其他错误通用处理
            ////todo  未来会集成Entlib 以实现动态配置的错误处理策略
            if (actionExecutedContext.Exception is ValidateException)
            {
                var error = new ResponseResultInfo();

                actionExecutedContext.Response =
                    actionExecutedContext.Request.CreateResponse(HttpStatusCode.ServiceUnavailable, error);
            }
            else if (actionExecutedContext.Exception is SpException)
            {
                //IDBErrorRepository dbErrorRepository = new DBErrorRepository();
                //dbErrorRepository.DBErrorLog();
                var dbexception =
                    actionExecutedContext.Exception as SpException;
                actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.ServiceUnavailable,
                    actionExecutedContext.Exception);
            }
            else if (actionExecutedContext.Exception is SqlExecuteException)
            {
                var dbexception =
                    actionExecutedContext.Exception as SqlExecuteException;
                var error = new ResponseResultInfo();
                error.errormodel = dbexception.ErrorModel;
                actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.BadRequest, error);
            }
            //未知情况
            else
            {
                actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.ServiceUnavailable);
            }
        }
    }
}